import { dom } from '@knno/dom';
import IconUnchecked from '@mdi/svg/svg/checkbox-blank-outline.svg';
import IconChecked from '@mdi/svg/svg/checkbox-marked.svg';
import IconIndeterminate from '@mdi/svg/svg/checkbox-intermediate.svg';
import { checkStyle } from './check.css';
import { Checkable } from './checkable';
import { groupStyle } from '../group/group.css';
import { DATA } from '../symbol';

export type CheckState = boolean | 'half';

export class Checkbox extends Checkable {
	updateFacade(): void {
		const value = this.checked();
		let icon: string;
		if (value === 'half') {
			icon = this[DATA]?.indeterminate ?? IconIndeterminate;
		} else if (value) {
			icon = this[DATA]?.checked ?? IconChecked;
		} else {
			icon = this[DATA]?.unchecked ?? IconUnchecked;
		}
		this.root.remove(this.query(':scope>svg'));
		this.root.insert(dom.html(icon));
	}
	constructor() {
		super(
			dom.button(checkStyle).attr({
				checked: 'false',
				type: 'check',
			})
		);
		this.root.insert(dom.html(this[DATA]?.unchecked ?? IconUnchecked));
		this.on('click', () => {
			if (this.disabled()) return;
			const oldValue = this.checked();
			this.checked(this.checked() === 'half' ? true : !this.checked());
			if (oldValue != this.checked()) {
				this.emit(new Event('change'));
				if (this.parent().class().includes(groupStyle)) {
					this.parent().emit(new Event('change'));
				}
			}
		});
		this.on('update', (evt) => {
			this.checked(evt.detail.checked);
		});
	}

	checked(): CheckState;
	checked(value: CheckState): this;
	checked(value?: CheckState): this | CheckState {
		const checked = this.attr('checked');
		const currentValue = checked === 'half' ? checked : checked === 'true' ? true : false;
		if (value === undefined) {
			return currentValue;
		} else {
			if (currentValue !== value) {
				this.attr('checked', value === 'half' ? value : value ? 'true' : null);
				this.updateFacade();
			}
			return this;
		}
	}
}

export function checkbox(...className: string[]): Checkbox {
	return new Checkbox().addClass(...className);
}
